﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Security.Cryptography;
#if Protobuf
using Google.Protobuf;
using Google.Protobuf.Collections;
#endif
public static class CommonFunctions
{
    //获取当前时间
    public static long GetTimeStamp()
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0);
        long ret = ts.Ticks;
        return ret;
    }
    
    public static double GetTimeStampSeconds()
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0);
        return ts.TotalSeconds;
    }

    public static DateTime TimeStampSeconds2DateTime(double timeStamp)
    {
        return new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(timeStamp);
    }

    public static byte[] GetBase64EncodeBytes(byte[] packet)
    {
        string base64Str = Convert.ToBase64String(packet);
        byte[] data = System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(base64Str);

        return data;
    }

    public static byte[] GetBase64DecodeBytes(byte[] packet)
    {
        string base64Str = System.Text.Encoding.GetEncoding("ISO-8859-1").GetString(packet);
        byte[] data = Convert.FromBase64String(base64Str);

        return data;
    }

#if Protobuf
    public static byte[] Serialize<T>(T model) where T: IMessage
    {
        try
        {
            return model.ToByteArray();
        }
        catch (System.Exception ex)
        {
            GameDebug.Log("序列化失败: " + ex.Message+"\n"+ex.StackTrace);
            return null;
        }
    }

    public static T Deserialize<T>(byte[] data) where T : IMessage,new()
    {
        T res = new T();
        try
        {
            res = new T();
            res = (T)res.Descriptor.Parser.ParseFrom(data);
            return res;
        }
        catch (System.Exception ex)
        {
            GameDebug.LogError($"反序列化失败  data.length:{data.Length}  \n ");
            GameDebug.LogError(ex.Message+"\n"+ex.StackTrace);
            GameDebug.Log($"\nbytes:{BitConverter.ToString(data)}");

        }
        return res;
    }
    public static T Deserialize<T>(byte[] data,int index,int count) where T : IMessage, new()
    {
        T res = new T();
        try
        {
            res = (T)res.Descriptor.Parser.ParseFrom(data,index,count);
            return res;
        }
        catch (System.Exception ex)
        {
            GameDebug.LogError("反序列化失败:\n ");
            GameDebug.LogError(ex);
            GameDebug.Log($"\nbytes:{BitConverter.ToString(data)}");

        }
        return res;
    }

    public static void ProtoListSetValue(this RepeatedField<int> repeatedField,List<int> value)
    {
        value.ForEach(e => { repeatedField.Add(e); });
    }
#endif
    private static RNGCryptoServiceProvider m_RNG = new RNGCryptoServiceProvider();

    public static int RandomRange(int min, int max)
    {
        byte[] buffer = new byte[4];
        m_RNG.GetBytes(buffer);

        int value = BitConverter.ToInt32(buffer, 0);
        if (value < 0) value = -value;
        return min + (value % (max - min));
    }

    public static string CompressJson(string json)
    {
        byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(json);

        using (MemoryStream compressedStream = new MemoryStream())
        {
            using (GZipStream compressionStream = new GZipStream(compressedStream, CompressionMode.Compress))
            {
                compressionStream.Write(jsonBytes, 0, jsonBytes.Length);
            }

            return Convert.ToBase64String(compressedStream.ToArray());
        }
    }

    public static string DecompressJson(string compressedJson)
    {
        byte[] compressedBytes = Convert.FromBase64String(compressedJson);

        using (MemoryStream decompressedStream = new MemoryStream())
        {
            using (MemoryStream compressedStream = new MemoryStream(compressedBytes))
            using (GZipStream decompressionStream = new GZipStream(compressedStream, CompressionMode.Decompress))
            {
                decompressionStream.CopyTo(decompressedStream);
            }

            return System.Text.Encoding.UTF8.GetString(decompressedStream.ToArray());
        }
    }
}

